/**
 * Copyright 2013 ABSir's Studio
 * 
 * All right reserved
 *
 * Create on 2013-6-17 下午4:26:43
 */
package com.absir.android.orm;

import java.sql.SQLException;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

import com.absir.android.view.InjectViewUtils;
import com.absir.bean.basis.Configure;
import com.absir.bean.core.BeanFactoryUtils;
import com.absir.core.kernel.KernelDyna;
import com.absir.core.kernel.KernelLang;
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
import com.j256.ormlite.dao.BaseDaoImpl;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableInfo;
import com.j256.ormlite.table.TableUtils;

/**
 * @author absir
 * 
 */
@Configure
public class DaoHelper extends OrmLiteSqliteOpenHelper {

	/** TAG */
	private static final String TAG = DaoHelper.class.getSimpleName();

	/** Dao_Helper */
	private static IDaoHelper Dao_Helper;

	/** Database_Version */
	private static int Database_Version;

	/**
	 * 获取数据库版本号
	 * 
	 * @param context
	 * @return
	 */
	protected static int getDataVersion(Context context) {
		if (Database_Version == 0) {
			Integer versionId = InjectViewUtils.getResouceId("string", "data_version");
			if (versionId != null) {
				Integer version = KernelDyna.toInteger(context.getResources().getString(versionId));
				if (version != null) {
					Database_Version = version;
				}
			}

			if (Database_Version == 0) {
				Database_Version = 1;
			}
		}

		return Database_Version;
	}

	/**
	 * @param context
	 * @param dataBaseName
	 */
	public DaoHelper(Context context, String dataBaseName) {
		super(context, dataBaseName, null, getDataVersion(context));
		Dao_Helper = BeanFactoryUtils.get(IDaoHelper.class);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper#onCreate(android
	 * .database.sqlite.SQLiteDatabase,
	 * com.j256.ormlite.support.ConnectionSource)
	 */
	@Override
	public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {
		// TODO Auto-generated method stub
		Log.d(TAG, "create db " + database.getVersion());
		if (Dao_Helper != null) {
			if (Dao_Helper.onCreate(database, connectionSource)) {
				return;
			}
		}

		for (Class<?> tableType : DaoFactory.Table_Types) {
			try {
				TableUtils.createTable(connectionSource, tableType);
			} catch (Exception e) {
				Log.e(TAG, "create table " + tableType + " error", e);
			}
		}
	}

	/** MIGRATE_TMP_TABLE_NAME */
	private static String MIGRATE_TMP_TABLE_NAME = "migrate_tmp_table";

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper#onUpgrade(android
	 * .database.sqlite.SQLiteDatabase,
	 * com.j256.ormlite.support.ConnectionSource, int, int)
	 */
	@Override
	public void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) {
		// TODO Auto-generated method stub
		if (Dao_Helper != null) {
			if (Dao_Helper.onUpgrade(database, connectionSource, oldVersion, newVersion)) {
				return;
			}
		}

		for (Class<?> tableType : DaoFactory.Table_Types) {
			try {
				Dao<Object, ?> dao = getDao(tableType);
				TableInfo<Object, ?> tableInfo = getTableInfo(dao, connectionSource);
				try {
					database.execSQL("ALTER TABLE " + tableInfo.getTableName() + " RENAME TO " + MIGRATE_TMP_TABLE_NAME);
					TableUtils.createTable(connectionSource, tableType);
					Cursor cursor = database.rawQuery("SELECT * FROM " + MIGRATE_TMP_TABLE_NAME, KernelLang.NULL_STRINGS);
					String[] culomnNames = null;
					while (cursor.moveToNext()) {
						if (culomnNames == null) {
							culomnNames = DaoCursorUtils.getCulomnNames(cursor);
						}

						try {
							Object bean = dao.getRawRowMapper().mapRow(culomnNames, DaoCursorUtils.getResultColumns(cursor));
							dao.createOrUpdate(bean);

						} catch (Exception e) {
							// TODO: handle exception
							Log.e(TAG, "upgrade raw row mapper " + tableType + " error", e);
						}
					}

				} catch (Exception e) {
					// TODO: handle exception
					Log.e(TAG, "upgrade migrate table " + tableType + " error", e);

				} finally {
					// TODO: handle exception
					database.execSQL("DROP TABLE " + MIGRATE_TMP_TABLE_NAME);
				}

			} catch (Exception e) {
				Log.e(TAG, "upgrade tableinfo " + tableType + " error", e);
			}
		}
	}

	/**
	 * @param dao
	 * @param connectionSource
	 * @return
	 * @throws SQLException
	 */
	public static <T, ID> TableInfo<T, ID> getTableInfo(Dao<T, ID> dao, ConnectionSource connectionSource) throws SQLException {
		if (dao instanceof BaseDaoImpl<?, ?>) {
			return ((BaseDaoImpl<T, ID>) dao).getTableInfo();

		} else {
			return new TableInfo<T, ID>(connectionSource, null, dao.getDataClass());
		}
	}
}
